<!--
  本组件实现下拉刷新和上拉无限加载功能。
  v0.0.1版 只实现上拉无限加载功能
-->
<template>
  <div class="pagination noscroll-bar" @scroll='scrollEvent'>
    <!--下拉刷新提示信息区域，可覆写-->
    <slot name='overwrite-down-warp'></slot>
    <!--列表区域-->
    <slot></slot>
    <!--上拉加载提示信息区域，可覆写-->
    <slot name='overwrite-up-warp'>
      <div class="up-content" :class="{'hardware up-content-show':isUpScrolling}">
        <p class="up-progress" :class="{'up-progress-rotate':isUpScrolling}"></p>
        <p class="up-tip">加载中... </p>
      </div>
      <div class="up-nomore" :class="{'up-nomore-show': upNoMoreData}">--  没有更多了  --</div>
    </slot>
    <div class="up-totop" :class="{'up-totop-show':toTop.showFlag}" @click="gotoTop">
      <icon class="up-totop-icon" name='back-to-top' scale='3'></icon>
    </div>
  </div>
</template>
<script>
import Icon from '../icon'
export default {
  data () {
    return {
      preScrollY: 0, // 滚动前的位置
      isUpScrolling: false, // 是否在加载中
      init: false,
      upNoMoreData: false,
      offset: 20, // 列表滚动距离底部20px的位置，触发上拉加载的回调
      page: {current: 0, size: 0, perPage: 10}, // 分页对象
      toTop: {
        offset: 1000, // 列表滚动多少距离才显示回到顶部按钮
        duration: 300, // 回到顶部的动画时长,默认300ms
        showFlag: false
      }
    }
  },
  components: {
    Icon
  },
  mounted () {
    this.init = true
    this.scrollEvent()
  },
  methods: {
    /**
     * 滚动事件回调，当触底时触发triggerUpScroll
     */
    scrollEvent () {
      var isUp = this.$el.scrollTop - this.preScrollY > 0 // 向上滑还是向下滑动
      if (this.init)isUp = true
      this.preScrollY = this.$el.scrollTop

      if (this.preScrollY >= this.toTop.offset) {
        this.toTop.showFlag = true
      } else {
        this.toTop.showFlag = false
      }

      if (!this.isUpScrolling) {
        var toBottom = this.$el.scrollHeight - this.$el.clientHeight - this.$el.scrollTop // 滚动条距离底部的距离
        if (toBottom <= this.offset && isUp && !this.upNoMoreData) {
          // 如果滚动条距离底部指定范围内且向上滑,则执行上拉加载回调
          this.triggerUpScroll()
        }
      }
    },
    /**
     * 触底时触发
     */
    triggerUpScroll () {
      this.init = false
      this.isUpScrolling = true
      this.page.current++
      this.$emit('loadMore', this.page)
      console.log('滚动到底部啦')
    },
    /**
     * 数据加载完成回调
     */
    endUpScroll (page) {
      this.page = page
      this.isUpScrolling = false
      if (page.current * this.page.perPage >= this.page.size) {
        this.upNoMoreData = true
      }
    },
    /**
     * 回到顶部
     */
    gotoTop () {
      const start = this.$el.scrollTop
      const end = 0
      this.pedometer(start, end, (step) => {
        this.$nextTick(() => {
          this.$el.scrollTop = step
        })
        console.log(step)
      }, 300, 30)
    },
    /**
     * 计步器
     */
    pedometer (star, end, callback, t, rate) {
      var diff = end - star // 差值
      if (t === 0 || diff === 0) {
        callback && callback(end)
        return
      }
      t = t || 300 // 时长 300ms
      rate = rate || 30 // 周期 30ms
      var count = t / rate // 次数
      var step = diff / count // 步长
      var i = 0 // 计数
      var timer = window.setInterval(function () {
        if (i < count - 1) {
          star += step
          callback && callback(star, timer)
          i++
        } else {
          callback && callback(end, timer) // 最后一次直接设置end,避免计算误差
          console.log('wan')
          window.clearInterval(timer)
        }
      }, rate)
    }
  }
}
</script>
<style lang="scss" scoped>
.pagination{
  position: absolute;
  top:0;
  left:0;
  width: 100%;
  bottom:0;
  overflow-y: scroll;
  .hardware {
    -webkit-transform: translateZ(0);
    -webkit-transform-style: preserve-3d;
    -webkit-backface-visibility: hidden;
    -webkit-perspective: 1000;
  }
  .up-content{
    min-height: 60px;
    padding: 30px 0;
    text-align: center;
    visibility: hidden;
    &-show{
      visibility: visible;
    }
    .up-progress{
      display: inline-block;
      width: 32px;
      height: 32px;
      border-radius: 50%;
      border: 1px solid gray;
      margin-right: 16px;
      border-bottom-color: transparent;
      vertical-align: middle;
    }
    .up-progress-rotate{
      animation:mescrollRotate .6s linear infinite
    }
    .up-tip{
      display: inline-block;
      font-size: 24px;
      color: gray;
      vertical-align: middle;
    }
  }
  .up-nomore{
    display: none;
    text-align: center;
    color: #ccc;
    margin-top: -50px;
  }
  .up-nomore-show{
    display: block;
  }
  .up-totop{
    position: fixed;
    bottom: 120px;
    right: 50px;
    display: none;
    &-icon{
      width: 50px;
      height: 50px;
      border-radius: 50%;
    }
    &-show{
      display: block;
    }
  }
}
@keyframes mescrollRotate {
0%{
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
</style>
